﻿using SlimDX;
using SlimDX.Direct3D11;
using SlimDX.DXGI;
using SlimDX.Windows;
using Device = SlimDX.Direct3D11.Device;
using Resource = SlimDX.Direct3D11.Resource;
using System.Drawing;
using System.Windows.Forms;
using ParticlesEngine.Core;
using SlimDX.D3DCompiler;

namespace Viewer
{
    public partial class Viewer : RenderForm
    {
        Device device = null;
        SwapChain swapChain = null;
        RenderTargetView renderTarget;
        DeviceContext context;
        public SceneManager sceneManager;
        ParticlesEngine.ParticlesSystem particlesSystem;

        public Viewer(string title)
        {
            InitializeComponent();
            this.Text = title;

        }
        public void InitializeGraphics()
        {
            var description = new SwapChainDescription()
            {
                BufferCount = 1,
                Usage = Usage.RenderTargetOutput,
                OutputHandle = this.Handle,
                IsWindowed = true,
                ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                SampleDescription = new SampleDescription(1, 0),
                Flags = SwapChainFlags.AllowModeSwitch,
                SwapEffect = SwapEffect.Discard
                
            };
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, description, out device, out swapChain);
            using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
                renderTarget = new RenderTargetView(device, resource);
            context = device.ImmediateContext;
            var viewport = new Viewport(0.0f, 0.0f, this.ClientSize.Width, this.ClientSize.Height);          
            context.OutputMerger.SetTargets(renderTarget);
            context.Rasterizer.SetViewports(viewport);
            Factory factory = swapChain.GetParent<Factory>();
            factory.SetWindowAssociation(this.Handle, WindowAssociationFlags.IgnoreAll);
            sceneManager = new SceneManager(device, context);
            particlesSystem = new ParticlesEngine.ParticlesSystem(device);
        }

        public void Draw()
        {
            context.ClearRenderTargetView(renderTarget, new Color4(0.5f, 0.5f, 1.0f));
            sceneManager.Draw();
            swapChain.Present(0, PresentFlags.None);
        }

        public void UpdateFrame()
        {
            particlesSystem.CreateParticle(new Vector4(1.0f), new Vector4(1.0f));
        }



        private void zamknijToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        protected override void OnClosed(System.EventArgs e)
        {
            base.OnClosed(e);
            sceneManager.Dispose();
            renderTarget.Dispose();
            swapChain.Dispose();
            device.Dispose();
        }

        private void oProgramieToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            Program.aboutBox.ShowDialog();
        }


       public  void LoadShader(out ShaderSignature signature, out VertexShader vs, out PixelShader ps)
        {
            //ShaderSignature inputSignature;
            using (var bytecode = ShaderBytecode.CompileFromFile("triangle.fx", "VShader", "vs_4_0", ShaderFlags.None, EffectFlags.None))
            {
                signature = ShaderSignature.GetInputSignature(bytecode);
                vs = new VertexShader(device, bytecode);
            }

            // load and compile the pixel shader
            using (var bytecode = ShaderBytecode.CompileFromFile("triangle.fx", "PShader", "ps_4_0", ShaderFlags.None, EffectFlags.None))
                ps = new PixelShader(device, bytecode);
        }
       public Effect LoadEffect(string filename)
       {
           var bytecode = ShaderBytecode.CompileFromFile(filename, "fx_5_0", ShaderFlags.None, EffectFlags.None);
            return new Effect(device, bytecode);
       }

    }
}
